#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <sstream>
#include <regex>
#include <stdexcept>
#include <memory>
#include <cctype>
#include <functional>
#include <cstring>

using namespace std;

// 先声明工具函数
bool isWhitespace(char c)
{
    return c == ' ' || c == '\t' || c == '\n' || c == '\r';
}

// Utility functions - 使用指针优化
char *trim_inplace(char *str)
{
    if (!str)
        return nullptr;

    char *start = str;
    while (*start && isWhitespace(*start))
    {
        start++;
    }

    if (*start == '\0')
    {
        str[0] = '\0';
        return str;
    }

    char *end = start + strlen(start) - 1;
    while (end > start && isWhitespace(*end))
    {
        end--;
    }

    *(end + 1) = '\0';

    if (start != str)
    {
        memmove(str, start, end - start + 2);
    }

    return str;
}

string trim(const string &str)
{
    if (str.empty())
        return "";

    const char *cstr = str.c_str();
    const char *start = cstr;
    const char *end = cstr + str.length() - 1;

    while (start <= end && isWhitespace(*start))
        start++;
    while (end >= start && isWhitespace(*end))
        end--;

    if (start > end)
        return "";

    return string(start, end - start + 1);
}

void toUpperInplace(string &str)
{
    char *data = &str[0]; // 使用operator[]获取可写引用
    const size_t len = str.length();
    for (size_t i = 0; i < len; ++i)
    {
        data[i] = static_cast<char>(toupper(static_cast<unsigned char>(data[i])));
    }
}

string toUpper(const string &str)
{
    string result = str;
    toUpperInplace(result);
    return result;
}

void escapeSqlStringInplace(string &input)
{
    size_t write_pos = 0;
    size_t read_pos = 0;
    const size_t len = input.length();
    char *data = &input[0]; // 使用operator[]获取可写引用

    // 先计算需要多少额外空间
    size_t extra_space = 0;
    for (size_t i = 0; i < len; ++i)
    {
        if (data[i] == '\'')
            extra_space++;
    }

    if (extra_space == 0)
        return; // 不需要转义

    // 调整大小
    input.resize(len + extra_space);
    data = &input[0]; // 重新获取指针

    // 进行转义
    for (read_pos = 0; read_pos < len; ++read_pos)
    {
        if (data[read_pos] == '\'')
        {
            data[write_pos++] = '\'';
            data[write_pos++] = '\'';
        }
        else
        {
            data[write_pos++] = data[read_pos];
        }
    }

    input.resize(write_pos);
}

string escapeSqlString(const string &input)
{
    string result = input;
    escapeSqlStringInplace(result);
    return result;
}

void split_fast(const string &str, char delimiter, vector<string> &tokens)
{
    tokens.clear();
    if (str.empty())
        return;

    const char *start = str.c_str();
    const char *end = start;

    while (*end)
    {
        if (*end == delimiter)
        {
            if (end > start)
            {
                tokens.emplace_back(start, end - start);
            }
            start = end + 1;
        }
        end++;
    }

    if (end > start)
    {
        tokens.emplace_back(start, end - start);
    }
}

vector<string> split(const string &str, char delimiter)
{
    vector<string> tokens;
    split_fast(str, delimiter, tokens);
    return tokens;
}

// Data structures - 使用指针优化
struct FileFormatOptions
{
    string formatName;
    string type;
    map<string, string> formatOptions;

    // 添加移动构造函数
    FileFormatOptions(FileFormatOptions &&other) noexcept
        : formatName(std::move(other.formatName)), type(std::move(other.type)), formatOptions(std::move(other.formatOptions))
    {
    }

    FileFormatOptions &operator=(FileFormatOptions &&other) noexcept
    {
        formatName = std::move(other.formatName);
        type = std::move(other.type);
        formatOptions = std::move(other.formatOptions);
        return *this;
    }

    FileFormatOptions() = default;
};

struct StageConfig
{
    string name;
    bool replace = false;
    bool ifNotExists = false;
    string storageIntegration;
    string url;
    string credentials;
    unique_ptr<FileFormatOptions> fileFormat;
    map<string, string> copyOptions;
    string comment;

    // 添加移动语义
    StageConfig(StageConfig &&other) noexcept
        : name(std::move(other.name)), replace(other.replace), ifNotExists(other.ifNotExists), storageIntegration(std::move(other.storageIntegration)), url(std::move(other.url)), credentials(std::move(other.credentials)), fileFormat(std::move(other.fileFormat)), copyOptions(std::move(other.copyOptions)), comment(std::move(other.comment))
    {
    }

    StageConfig &operator=(StageConfig &&other) noexcept
    {
        name = std::move(other.name);
        replace = other.replace;
        ifNotExists = other.ifNotExists;
        storageIntegration = std::move(other.storageIntegration);
        url = std::move(other.url);
        credentials = std::move(other.credentials);
        fileFormat = std::move(other.fileFormat);
        copyOptions = std::move(other.copyOptions);
        comment = std::move(other.comment);
        return *this;
    }

    StageConfig() = default;
};

struct ColumnInfo
{
    string name;
    string dataType;
    string comment;

    ColumnInfo(ColumnInfo &&other) noexcept
        : name(std::move(other.name)), dataType(std::move(other.dataType)), comment(std::move(other.comment))
    {
    }

    ColumnInfo &operator=(ColumnInfo &&other) noexcept
    {
        name = std::move(other.name);
        dataType = std::move(other.dataType);
        comment = std::move(other.comment);
        return *this;
    }

    ColumnInfo() = default;
};

struct HiveTableInfo
{
    string tableName;
    bool orReplace = false;
    bool ifNotExists = false;
    vector<ColumnInfo> columns;
    string tableComment;
    vector<string> partitionColumns;
    vector<string> clusteredColumns;
    string storageFormat;
    string location;

    HiveTableInfo(HiveTableInfo &&other) noexcept
        : tableName(std::move(other.tableName)), orReplace(other.orReplace), ifNotExists(other.ifNotExists), columns(std::move(other.columns)), tableComment(std::move(other.tableComment)), partitionColumns(std::move(other.partitionColumns)), clusteredColumns(std::move(other.clusteredColumns)), storageFormat(std::move(other.storageFormat)), location(std::move(other.location))
    {
    }

    HiveTableInfo &operator=(HiveTableInfo &&other) noexcept
    {
        tableName = std::move(other.tableName);
        orReplace = other.orReplace;
        ifNotExists = other.ifNotExists;
        columns = std::move(other.columns);
        tableComment = std::move(other.tableComment);
        partitionColumns = std::move(other.partitionColumns);
        clusteredColumns = std::move(other.clusteredColumns);
        storageFormat = std::move(other.storageFormat);
        location = std::move(other.location);
        return *this;
    }

    HiveTableInfo() = default;
};

// 使用函数指针优化多态行为
using StringProcessorFunc = function<string(const string &)>;
using ClauseGeneratorFunc = function<void(const StageConfig &, vector<string> &)>;

// Stage SQL Generator - 使用函数指针优化
class StageSqlGenerator
{
private:
    static vector<ClauseGeneratorFunc> clauseGenerators;

public:
    static void initialize()
    {
        if (clauseGenerators.empty())
        {
            clauseGenerators.push_back([](const StageConfig &config, vector<string> &clauses)
                                       { addStorageIntegration(config, clauses); });
            clauseGenerators.push_back([](const StageConfig &config, vector<string> &clauses)
                                       { addUrl(config, clauses); });
            clauseGenerators.push_back([](const StageConfig &config, vector<string> &clauses)
                                       { addCredentials(config, clauses); });
            clauseGenerators.push_back([](const StageConfig &config, vector<string> &clauses)
                                       { addFileFormat(config, clauses); });
            clauseGenerators.push_back([](const StageConfig &config, vector<string> &clauses)
                                       { addCopyOptions(config, clauses); });
            clauseGenerators.push_back([](const StageConfig &config, vector<string> &clauses)
                                       { addComment(config, clauses); });
        }
    }

    static string generateCreateStageSql(const StageConfig &config)
    {
        string replaceModifier = config.replace ? "OR REPLACE " : "";
        string ifNotExistsModifier = config.ifNotExists ? "IF NOT EXISTS " : "";
        vector<string> clauses;

        // 使用函数指针数组批量处理
        for (const auto &generator : clauseGenerators)
        {
            generator(config, clauses);
        }

        return formatFinalSql(config, replaceModifier, ifNotExistsModifier, clauses);
    }

private:
    static void addStorageIntegration(const StageConfig &config, vector<string> &clauses)
    {
        if (!config.storageIntegration.empty())
        {
            clauses.push_back("STORAGE INTEGRATION = " + config.storageIntegration);
        }
    }

    static void addUrl(const StageConfig &config, vector<string> &clauses)
    {
        if (!config.url.empty())
        {
            clauses.push_back("URL = '" + escapeSqlString(config.url) + "'");
        }
    }

    static void addCredentials(const StageConfig &config, vector<string> &clauses)
    {
        if (!config.credentials.empty())
        {
            clauses.push_back("CREDENTIALS = ( " + config.credentials + " )");
        }
    }

    static void addFileFormat(const StageConfig &config, vector<string> &clauses)
    {
        if (!config.fileFormat)
            return;

        const auto &ff = *config.fileFormat;
        if (!ff.formatName.empty())
        {
            clauses.push_back("FILE_FORMAT = ( FORMAT_NAME = '" + escapeSqlString(ff.formatName) + "' )");
        }
        else if (!ff.type.empty())
        {
            string typeClause = "TYPE = " + ff.type;
            vector<string> options;
            options.reserve(ff.formatOptions.size());

            for (const auto &kv : ff.formatOptions)
            {
                options.push_back(kv.first + " = " + kv.second);
            }

            if (!options.empty())
            {
                string optionsStr = typeClause;
                for (size_t i = 0; i < options.size(); ++i)
                {
                    optionsStr += ", " + options[i];
                }
                clauses.push_back("FILE_FORMAT = ( " + optionsStr + " ) ");
            }
            else
            {
                clauses.push_back("FILE_FORMAT = ( " + typeClause + " ) ");
            }
        }
    }

    static void addCopyOptions(const StageConfig &config, vector<string> &clauses)
    {
        if (config.copyOptions.empty())
            return;

        vector<string> options;
        options.reserve(config.copyOptions.size());

        for (const auto &kv : config.copyOptions)
        {
            options.push_back(kv.first + "=" + kv.second);
        }

        string optionsStr;
        for (size_t i = 0; i < options.size(); ++i)
        {
            if (i > 0)
                optionsStr += ", ";
            optionsStr += options[i];
        }
        clauses.push_back("COPY_OPTIONS = (" + optionsStr + " )");
    }

    static void addComment(const StageConfig &config, vector<string> &clauses)
    {
        if (!config.comment.empty())
        {
            clauses.push_back("COMMENT = '" + escapeSqlString(config.comment) + "'");
        }
    }

    static string formatFinalSql(const StageConfig &config, const string &replaceModifier, const string &ifNotExistsModifier, const vector<string> &clauses)
    {
        string result;
        result.reserve(256); // 预分配空间

        result = "CREATE " + replaceModifier + "STAGE " + ifNotExistsModifier + config.name;
        if (!clauses.empty())
        {
            result += "\n ";
            for (size_t i = 0; i < clauses.size(); ++i)
            {
                if (i > 0)
                    result += "\n ";
                result += clauses[i];
            }
            result += ";\n";
        }
        else
        {
            result += ";\n";
        }
        return result;
    }
};

// 初始化静态成员
vector<ClauseGeneratorFunc> StageSqlGenerator::clauseGenerators;

// HiveQL Parser - 使用指针优化字符串处理
class HiveQLParser
{
public:
    static bool parseCreateTableStatement(const string &input, bool &isExternal, bool &isTemporary)
    {
        isExternal = false;
        isTemporary = false;

        const char *data = input.c_str();
        int index = 0;
        int len = static_cast<int>(input.length());

        if (!matchWhitespaceAndKeyword(data, len, index, "CREATE"))
            return false;
        if (!matchOptionalClause(data, len, index, isExternal, isTemporary))
            return false;
        if (!matchWhitespaceAndKeyword(data, len, index, "TABLE"))
            return false;

        return index < len && isWhitespace(data[index]);
    }

private:
    static bool matchOptionalClause(const char *input, int len, int &index, bool &isExternal, bool &isTemporary)
    {
        int savedIndex = index;
        bool foundOrReplace = false;

        // Try to match OR REPLACE first
        if (matchWhitespaceAndKeyword(input, len, index, "OR"))
        {
            if (matchWhitespaceAndKeyword(input, len, index, "REPLACE"))
            {
                foundOrReplace = true;
                savedIndex = index;
            }
            else
            {
                index = savedIndex;
                return true;
            }
        }

        // Try to match EXTERNAL
        if (matchWhitespaceAndKeyword(input, len, index, "EXTERNAL"))
        {
            isExternal = true;
            return true;
        }

        // Try to match TEMPORARY
        if (matchWhitespaceAndKeyword(input, len, index, "TEMPORARY"))
        {
            isTemporary = true;
            return true;
        }

        if (foundOrReplace)
        {
            return true;
        }

        index = savedIndex;
        return true;
    }

    static bool matchWhitespaceAndKeyword(const char *input, int len, int &index, const string &keyword)
    {
        while (index < len && isWhitespace(input[index]))
            index++;
        return matchKeyword(input, len, index, keyword);
    }

    static bool matchKeyword(const char *input, int len, int &index, const string &keyword)
    {
        int keywordLen = static_cast<int>(keyword.length());
        if (index + keywordLen > len)
            return false;

        for (int i = 0; i < keywordLen; i++)
        {
            if (toupper(input[index + i]) != toupper(keyword[i]))
                return false;
        }

        index += keywordLen;
        return true;
    }
};

// String Processor - 使用指针优化字符串操作
class StringProcessor
{
public:
    string processString(const string &input)
    {
        if (input.empty())
            return input;

        // 先预处理复杂数据类型
        string result = preprocessComplexTypes(input);
        result = replaceCommaSpaces(result);

        // ... 其余处理逻辑保持不变
        auto outerPairs = findOuterParenthesesPairs(result);
        vector<int> insertPositions;
        insertPositions.reserve(outerPairs.size() * 2);

        for (const auto &pair : outerPairs)
        {
            int start = pair.first;
            int end = pair.second;

            if (start > end || start < 0 || end >= static_cast<int>(result.length()))
                continue;

            string substr = result.substr(start, end - start + 1);
            auto groups = splitIntoGroups(substr);

            for (const auto &group : groups)
            {
                if (group.first < 0 || group.second >= static_cast<int>(substr.length()) || group.first > group.second)
                    continue;

                bool hasLT = false, hasGT = false;
                const char *subdata = substr.c_str();
                for (int i = group.first; i <= group.second; i++)
                {
                    char c = subdata[i];
                    if (c == '<')
                        hasLT = true;
                    else if (c == '>')
                        hasGT = true;
                    if (hasLT && hasGT)
                        break;
                }
                if (hasLT && hasGT)
                {
                    insertPositions.push_back(start + group.first);
                    insertPositions.push_back(start + group.second + 1);
                }
            }
        }

        sort(insertPositions.begin(), insertPositions.end(), greater<int>());
        for (int pos : insertPositions)
        {
            if (pos >= 0 && pos <= static_cast<int>(result.length()))
            {
                result.insert(pos, 1, '`');
            }
        }

        return result;
    }

private:
    string preprocessComplexTypes(const string &input)
    {
        string result = input;

        // 保护复杂数据类型中的内容不被错误处理
        // 临时替换复杂数据类型中的逗号，避免被错误分割
        vector<pair<size_t, size_t>> complexTypeRanges;

        size_t pos = 0;
        while (pos < result.length())
        {
            // 寻找复杂数据类型的开始
            size_t arrayPos = result.find("ARRAY<", pos);
            size_t mapPos = result.find("MAP<", pos);
            size_t structPos = result.find("STRUCT<", pos);
            size_t unionPos = result.find("UNIONTYPE<", pos);

            size_t nextPos = string::npos;
            string typeMarker;

            // 找到最左边的复杂类型
            if (arrayPos != string::npos)
            {
                nextPos = arrayPos;
                typeMarker = "ARRAY<";
            }
            if (mapPos != string::npos && (nextPos == string::npos || mapPos < nextPos))
            {
                nextPos = mapPos;
                typeMarker = "MAP<";
            }
            if (structPos != string::npos && (nextPos == string::npos || structPos < nextPos))
            {
                nextPos = structPos;
                typeMarker = "STRUCT<";
            }
            if (unionPos != string::npos && (nextPos == string::npos || unionPos < nextPos))
            {
                nextPos = unionPos;
                typeMarker = "UNIONTYPE<";
            }

            if (nextPos == string::npos)
                break;

            // 找到匹配的结束尖括号
            size_t start = nextPos + typeMarker.length() - 1; // 包含 <
            size_t end = findMatchingAngleBracket(result, start);

            if (end != string::npos)
            {
                complexTypeRanges.push_back({nextPos, end});
                pos = end + 1;
            }
            else
            {
                pos = nextPos + 1;
            }
        }

        return result;
    }

    size_t findMatchingAngleBracket(const string &str, size_t startPos)
    {
        int depth = 1;
        for (size_t i = startPos + 1; i < str.length(); i++)
        {
            if (str[i] == '<')
                depth++;
            else if (str[i] == '>')
                depth--;

            if (depth == 0)
                return i;
        }
        return string::npos;
    }

    vector<pair<int, int>> findOuterParenthesesPairs(const string &input)
    {
        vector<pair<int, int>> pairs;
        int depth = 0;
        int currentStart = -1;
        const char *data = input.c_str();
        int len = static_cast<int>(input.length());

        for (int i = 0; i < len; i++)
        {
            char c = data[i];
            if (c == '(')
            {
                depth++;
                if (depth == 1)
                    currentStart = i + 1;
            }
            else if (c == ')')
            {
                depth--;
                if (depth == 0 && currentStart != -1)
                {
                    int currentEnd = i - 1;
                    if (currentStart <= currentEnd)
                    {
                        pairs.push_back({currentStart, currentEnd});
                    }
                    currentStart = -1;
                }
            }
        }
        return pairs;
    }

    vector<pair<int, int>> splitIntoGroups(const string &substr)
    {
        vector<pair<int, int>> groups;
        int currentGroupStart = -1;
        const char *data = substr.c_str();
        int len = static_cast<int>(substr.length());

        for (int i = 0; i < len; i++)
        {
            if (isWhitespace(data[i]))
            {
                if (currentGroupStart != -1)
                {
                    groups.push_back({currentGroupStart, i - 1});
                    currentGroupStart = -1;
                }
            }
            else if (currentGroupStart == -1)
            {
                currentGroupStart = i;
            }
        }

        if (currentGroupStart != -1)
        {
            groups.push_back({currentGroupStart, len - 1});
        }

        return groups;
    }

    string replaceCommaSpaces(const string &input)
    {
        if (input.empty())
            return input;

        string result = input;
        char *data = &result[0]; // 使用operator[]获取可写引用
        size_t len = result.length();
        bool changed;

        do
        {
            changed = false;
            size_t write_pos = 0;
            size_t read_pos = 0;

            // 单次遍历处理所有替换
            while (read_pos < len)
            {
                if (read_pos + 1 < len)
                {
                    if ((data[read_pos] == ',' && data[read_pos + 1] == ' ') ||
                        (data[read_pos] == ' ' && data[read_pos + 1] == ','))
                    {
                        data[write_pos++] = ',';
                        read_pos += 2;
                        changed = true;
                        continue;
                    }
                    if ((data[read_pos] == ' ' && data[read_pos + 1] == ':') ||
                        (data[read_pos] == ':' && data[read_pos + 1] == ' '))
                    {
                        data[write_pos++] = ':';
                        read_pos += 2;
                        changed = true;
                        continue;
                    }
                }
                data[write_pos++] = data[read_pos++];
            }

            len = write_pos;
            result.resize(len);

        } while (changed);

        // 处理 ">," 替换为 "> ,"
        size_t pos = 0;
        while ((pos = result.find(">,", pos)) != string::npos)
        {
            result.replace(pos, 2, "> ,");
            pos += 3;
        }

        return result;
    }
};

// Hive to Snowflake Converter - 使用指针和缓存优化
class HiveToSnowflakeConverter
{
private:
    map<string, string> dataTypeMapping;
    mutable map<string, string> typeCache; // 类型映射缓存

public:
    bool external_table_auto_refresh = false;
    string external_table_bucket_prefix;
    string external_table_aws_sns_topic;
    string external_table_aws_key_id;
    string external_table_aws_secret_key;
    string external_table_field_delimiter;
    int external_table_field_skip_header = 0;

    HiveToSnowflakeConverter()
    {
        initializeDataTypeMapping();
        StageSqlGenerator::initialize();
    }

    string createTable(const string &hiveSql)
    {
        bool actualExternal, actualTemporary;
        bool result = HiveQLParser::parseCreateTableStatement(hiveSql, actualExternal, actualTemporary);

        if (!result)
            return "";

        if (actualExternal)
        {
            ValidateExternalTableConfig();
        }

        auto hiveTableInfo = parseHiveCreateTable(hiveSql);
        return generateSnowflakeCreateTable(hiveTableInfo, actualExternal, actualTemporary);
    }

private:
    void initializeDataTypeMapping()
    {
        dataTypeMapping = {
            {"TinyInt", "TINYINT"},
            {"SmallInt", "SMALLINT"},
            {"Int", "INT"},
            {"BigInt", "BIGINT"},
            {"Float", "FLOAT"},
            {"Double", "DOUBLE"},
            {"Decimal", "DECIMAL"},
            {"Boolean", "BOOLEAN"},
            {"StringType", "VARCHAR"},
            {"STRING", "VARCHAR"},
            {"Char", "CHAR"},
            {"VarChar", "VARCHAR"},
            {"Binary", "BINARY"},
            {"Timestamp", "TIMESTAMP"},
            {"Date", "DATE"},
            {"ARRAY", "ARRAY"},
            {"MAP", "VARCHAR"},
            {"STRUCT", "OBJECT"},
            {"UNIONTYPE", "VARCHAR"},
            {"INTERVAL", "VARCHAR"},
            {"TIMESTAMP WITH LOCAL TIME ZONE", "TIMESTAMP_LTZ"},
            {"TIMESTAMP WITH TIME ZONE", "TIMESTAMP_TZ"},
            {"TEXT", "VARCHAR"},
            {"REAL", "REAL"},
            {"NUMERIC", "NUMBER"}};
    }

    void ValidateExternalTableConfig()
    {
        if (external_table_bucket_prefix.empty())
            throw runtime_error("external_table_bucket_prefix is required for external tables");
        if (external_table_aws_key_id.empty())
            throw runtime_error("external_table_aws_key_id is required for external tables");
        if (external_table_aws_secret_key.empty())
            throw runtime_error("external_table_aws_secret_key is required for external tables");
        if (external_table_aws_sns_topic.empty())
            throw runtime_error("external_table_aws_sns_topic is required for external tables");
        if (external_table_field_delimiter.empty())
            throw runtime_error("external_table_field_delimiter is required for external tables");
    }

    HiveTableInfo parseHiveCreateTable(const string &hiveSql)
    {
        HiveTableInfo info;

        // 使用静态正则表达式避免重复构造
        static const regex tableNameRegex(R"(CREATE\s+(?:OR\s+REPLACE\s+)?(?:EXTERNAL\s+)?(?:TEMPORARY\s+)?TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?([^(\s]+(?:\s+[^(\s]+)*)\s*\()", regex::icase);
        static const regex tableCommentRegex(R"(\)\s*COMMENT\$+['\"]([^'\"]*)['\"])", regex::icase);
        static const regex partitionRegex(R"(PARTITIONED\s+BY\s*\(\s*([^)]+)\s*\))", regex::icase);
        static const regex clusterRegex(R"(CLUSTERED\s+BY\s*\(\*([^)]+)\s*\))", regex::icase);
        static const regex storageRegex(R"(STORED\s+AS\s+(\w+))", regex::icase);
        static const regex locationRegex(R"(LOCATION\s+['\"]([^'\"]*)['\"])", regex::icase);
        static const regex orReplaceRegex(R"(CREATE\s+OR\s+REPLACE)", regex::icase);
        static const regex ifNotExistsRegex(R"(IF\s+NOT\s+EXISTS)", regex::icase);

        smatch match;
        if (regex_search(hiveSql, match, tableNameRegex))
        {
            info.tableName = trim(match[1].str());
            replace(info.tableName.begin(), info.tableName.end(), '`', '"');
        }

        info.orReplace = regex_search(hiveSql, orReplaceRegex);
        info.ifNotExists = regex_search(hiveSql, ifNotExistsRegex);

        if (regex_search(hiveSql, match, tableCommentRegex))
        {
            info.tableComment = match[1].str();
        }

        if (regex_search(hiveSql, match, partitionRegex))
        {
            string partitionStr = match[1].str();
            auto parts = split(partitionStr, ',');
            for (const auto &part : parts)
            {
                string trimmed = trim(part);
                size_t spacePos = trimmed.find(' ');
                if (spacePos != string::npos)
                {
                    string colName = trim(trimmed.substr(0, spacePos));
                    colName.erase(remove(colName.begin(), colName.end(), '`'), colName.end());
                    info.partitionColumns.push_back(std::move(colName));
                }
            }
        }

        if (regex_search(hiveSql, match, clusterRegex))
        {
            string clusterStr = match[1].str();
            auto parts = split(clusterStr, ',');
            for (const auto &part : parts)
            {
                string trimmed = trim(part);
                trimmed.erase(remove(trimmed.begin(), trimmed.end(), '`'), trimmed.end());
                info.clusteredColumns.push_back(std::move(trimmed));
            }
        }

        if (regex_search(hiveSql, match, storageRegex))
        {
            info.storageFormat = match[1].str();
        }

        if (regex_search(hiveSql, match, locationRegex))
        {
            info.location = match[1].str();
        }

        string columnsStr = extractColumnDefinitions(hiveSql);
        if (!columnsStr.empty())
        {
            parseColumns(columnsStr, info.columns);
        }

        return info;
    }

    string extractColumnDefinitions(const string &sql)
    {
        size_t tablePos = sql.find("TABLE");
        if (tablePos == string::npos)
            return "";

        size_t openParen = sql.find('(', tablePos + 5);
        if (openParen == string::npos)
            return "";

        int depth = 1;
        size_t closeParen = openParen + 1;
        const char *data = sql.c_str();

        while (closeParen < sql.length() && depth > 0)
        {
            char c = data[closeParen];
            if (c == '(')
                depth++;
            else if (c == ')')
                depth--;
            closeParen++;
        }

        if (depth != 0)
            return "";

        return sql.substr(openParen + 1, closeParen - openParen - 2);
    }

    size_t findTypeStartPosition(const string &colDef)
    {
        bool inQuotes = false;
        char quoteChar = 0;
        const char *data = colDef.c_str();

        for (size_t i = 0; i < colDef.length(); i++)
        {
            char c = data[i];

            // 处理引号
            if ((c == '"' || c == '`') && !inQuotes)
            {
                inQuotes = true;
                quoteChar = c;
            }
            else if (inQuotes && c == quoteChar)
            {
                inQuotes = false;
            }
            else if (!inQuotes)
            {
                // 寻找第一个空格，这通常是列名和类型的分界
                if (isWhitespace(c))
                {
                    // 跳过连续的空格
                    while (i < colDef.length() && isWhitespace(data[i]))
                        i++;
                    return i;
                }
                // 如果遇到复杂数据类型的符号，说明列名已经结束
                else if (c == '<' || c == ':')
                {
                    return i;
                }
            }
        }

        return string::npos;
    }

    void extractDataTypeAndComment(const string &input, string &dataType, string &comment)
    {
        dataType = input;
        comment = "";

        static const regex commentRegex(R"(\s+COMMENT\s+['\"]([^'\"]*)['\"])", regex::icase);
        smatch match;

        if (regex_search(input, match, commentRegex))
        {
            comment = match[1].str();
            dataType = regex_replace(input, commentRegex, "");
        }

        dataType = trim(dataType);

        // 特殊处理：如果数据类型包含空格，可能是复杂类型的一部分
        // 我们需要保持复杂数据类型的完整性
        if (dataType.find(' ') != string::npos)
        {
            // 检查是否是复杂数据类型
            string upperType = toUpper(dataType);
            if (upperType.find("ARRAY<") == 0 ||
                upperType.find("MAP<") == 0 ||
                upperType.find("STRUCT<") == 0 ||
                upperType.find("UNIONTYPE<") == 0)
            {
                // 保持原样，让 mapHiveToSnowflakeType 处理
            }
            else
            {
                // 简单类型包含空格，取第一个单词
                size_t firstSpace = dataType.find(' ');
                dataType = dataType.substr(0, firstSpace);
            }
        }

        dataType = mapHiveToSnowflakeType(dataType);
    }

    string extractInnerType(const string &typeDef, const string &outerType)
    {
        size_t start = typeDef.find('<');
        if (start == string::npos)
            return "VARCHAR";

        size_t end = findMatchingAngleBracket(typeDef, start);
        if (end == string::npos || end <= start)
            return "VARCHAR";

        return trim(typeDef.substr(start + 1, end - start - 1));
    }

    size_t findMatchingAngleBracket(const string &str, size_t startPos)
    {
        int depth = 1;
        for (size_t i = startPos + 1; i < str.length(); i++)
        {
            if (str[i] == '<')
                depth++;
            else if (str[i] == '>')
                depth--;

            if (depth == 0)
                return i;
        }
        return string::npos;
    }

    void parseColumns(const string &columnsStr, vector<ColumnInfo> &columns)
    {
        if (columnsStr.empty())
            return;

        vector<string> columnDefs;
        string current;
        current.reserve(columnsStr.length());

        int parenDepth = 0;
        int angleDepth = 0;
        bool inSingleQuote = false;
        bool inDoubleQuote = false;
        const char *data = columnsStr.c_str();

        for (size_t i = 0; i < columnsStr.length(); i++)
        {
            char c = data[i];

            if (c == '\'' && !inDoubleQuote)
                inSingleQuote = !inSingleQuote;
            if (c == '"' && !inSingleQuote)
                inDoubleQuote = !inDoubleQuote;

            if (!inSingleQuote && !inDoubleQuote)
            {
                if (c == '(')
                    parenDepth++;
                else if (c == ')')
                    parenDepth--;
                else if (c == '<')
                    angleDepth++;
                else if (c == '>')
                    angleDepth--;
            }

            // 只有在不在引号中，且括号和尖括号深度为0时，才分割列
            if (c == ',' && parenDepth == 0 && angleDepth == 0 && !inSingleQuote && !inDoubleQuote)
            {
                if (!current.empty())
                {
                    columnDefs.push_back(trim(current));
                    current.clear();
                }
            }
            else
            {
                current += c;
            }
        }

        if (!current.empty())
        {
            columnDefs.push_back(trim(current));
        }

        columns.reserve(columnDefs.size());
        for (const string &colDef : columnDefs)
        {
            if (colDef.empty() || toUpper(colDef).find("CONSTRAINT") == 0)
                continue;

            ColumnInfo colInfo = parseSimpleColumn(colDef);
            if (!colInfo.name.empty())
            {
                columns.push_back(std::move(colInfo));
            }
        }
    }

    ColumnInfo parseSimpleColumn(const string &colDef)
    {
        ColumnInfo colInfo;

        // 简单的空格分割
        size_t spacePos = colDef.find(' ');
        if (spacePos == string::npos)
        {
            colInfo.name = cleanColumnName(colDef);
            colInfo.dataType = "VARCHAR";
            return colInfo;
        }

        string colName = trim(colDef.substr(0, spacePos));
        string remainder = trim(colDef.substr(spacePos));

        colInfo.name = cleanColumnName(colName);
        extractDataTypeAndComment(remainder, colInfo.dataType, colInfo.comment);

        return colInfo;
    }

    string cleanColumnName(const string &colName)
    {
        string cleaned = colName;
        // 移除反引号和引号
        cleaned.erase(remove(cleaned.begin(), cleaned.end(), '`'), cleaned.end());
        cleaned.erase(remove(cleaned.begin(), cleaned.end(), '"'), cleaned.end());

        // 如果列名包含空格或特殊字符，需要加引号
        if (cleaned.find(' ') != string::npos || cleaned.find('.') != string::npos)
        {
            if (cleaned[0] != '"')
            {
                cleaned = "\"" + cleaned + "\"";
            }
        }

        return cleaned;
    }

    string mapHiveToSnowflakeType(const string &hiveType)
    {
        if (hiveType.empty())
            return "VARCHAR";

        // 检查缓存
        auto cacheIt = typeCache.find(hiveType);
        if (cacheIt != typeCache.end())
        {
            return cacheIt->second;
        }

        string normalizedType = trim(hiveType);
        string upperHiveType = toUpper(normalizedType);

        // 首先检查精确匹配
        for (const auto &mapping : dataTypeMapping)
        {
            if (toUpper(normalizedType) == toUpper(mapping.first))
            {
                typeCache[hiveType] = mapping.second;
                return mapping.second;
            }
        }

        // 处理带参数的类型（DECIMAL, VARCHAR等）
        if (upperHiveType.find("DECIMAL(") == 0 ||
            upperHiveType.find("NUMERIC(") == 0 ||
            upperHiveType.find("VARCHAR(") == 0 ||
            upperHiveType.find("CHAR(") == 0)
        {
            typeCache[hiveType] = normalizedType;
            return normalizedType;
        }

        // 处理数组类型
        if (upperHiveType.find("ARRAY<") == 0)
        {
            string innerType = extractInnerType(normalizedType, "ARRAY");
            string mappedInnerType = mapHiveToSnowflakeType(innerType);
            string result = "ARRAY<" + mappedInnerType + ">";
            typeCache[hiveType] = result;
            return result;
        }

        // 处理 Map 类型
        if (upperHiveType.find("MAP<") == 0)
        {
            // 对于 Snowflake，MAP 通常转换为 OBJECT 或 VARIANT
            string result = "OBJECT";
            typeCache[hiveType] = result;
            return result;
        }

        // 处理 Struct 类型
        if (upperHiveType.find("STRUCT<") == 0)
        {
            string result = "OBJECT";
            typeCache[hiveType] = result;
            return result;
        }

        // 处理 UNIONTYPE 类型
        if (upperHiveType.find("UNIONTYPE<") == 0)
        {
            typeCache[hiveType] = "VARCHAR";
            return "VARCHAR";
        }

        // 默认回退到 VARCHAR
        typeCache[hiveType] = "VARCHAR";
        return "VARCHAR";
    }

    string generateSnowflakeCreateTable(const HiveTableInfo &info, bool actualExternal, bool actualTemporary)
    {
        vector<string> columns;
        columns.reserve(info.columns.size());

        for (const auto &col : info.columns)
        {
            string colDef = "    " + col.name + " " + col.dataType;
            if (!col.comment.empty())
            {
                colDef += " COMMENT '" + escapeSqlString(col.comment) + "'";
            }
            columns.push_back(std::move(colDef));
        }

        string partition = actualExternal ? "PARTITION" : "CLUSTERED";
        string partitionColumns;
        if (!info.partitionColumns.empty())
        {
            partitionColumns = "\n" + partition + " BY (";
            for (size_t i = 0; i < info.partitionColumns.size(); ++i)
            {
                if (i > 0)
                    partitionColumns += ", ";
                partitionColumns += info.partitionColumns[i];
            }
            partitionColumns += ")";
        }

        string format = (info.storageFormat == "TextFile") ? "CSV" : info.storageFormat;
        string tableName = processTableName(info.tableName);
        string stage = sanitizeStageName(info.tableName);

        string location;
        if (actualExternal)
        {
            location = "\nLOCATION = @" + stage + "\nAUTO REFRESH = " + (external_table_auto_refresh ? "TRUE" : "FALSE") + "\nFILE FORMAT = (TYPE " + format + ")" + "\nAWS SNS TOPIC = '" + escapeSqlString(external_table_aws_sns_topic) + "'";
        }

        string clusteredColumns;
        if (!info.clusteredColumns.empty())
        {
            clusteredColumns = "\nCLUSTERED BY(";
            for (size_t i = 0; i < info.clusteredColumns.size(); ++i)
            {
                if (i > 0)
                    clusteredColumns += ", ";
                clusteredColumns += info.clusteredColumns[i];
            }
            clusteredColumns += ")";
        }

        string tableComment;
        if (!info.tableComment.empty())
        {
            tableComment = "\nCOMMENT '" + escapeSqlString(info.tableComment) + "'";
        }

        string external = actualExternal ? "EXTERNAL " : "";
        string temporary = actualTemporary ? "TEMPORARY " : "";
        string sql;

        if (actualExternal)
        {
            StageConfig config;
            config.name = stage;
            config.replace = true;
            config.url = external_table_bucket_prefix + info.location;
            config.credentials = "AWS_KEY_ID='" + external_table_aws_key_id + "' AWS_SECRET_KEY='" + external_table_aws_secret_key + "'";

            config.fileFormat = make_unique<FileFormatOptions>();
            config.fileFormat->type = format;
            config.fileFormat->formatOptions["FIELD_DELIMITER"] = "'" + external_table_field_delimiter + "'";
            config.fileFormat->formatOptions["SKIP_HEADER"] = to_string(external_table_field_skip_header);
            config.copyOptions["ON_ERROR"] = "'CONTINUE'";
            config.comment = "stage for " + tableName;

            sql = StageSqlGenerator::generateCreateStageSql(config);
        }

        string orReplace = info.orReplace ? "OR REPLACE " : "";
        string ifNotExists = info.ifNotExists ? "IF NOT EXISTS " : "";
        sql += "\nCREATE " + orReplace + external + temporary + "TABLE " + ifNotExists + tableName + " (\n";

        if (!columns.empty())
        {
            for (size_t i = 0; i < columns.size(); ++i)
            {
                sql += columns[i];
                if (i < columns.size() - 1)
                    sql += ",";
                sql += "\n";
            }
        }

        sql += ")" + tableComment + partitionColumns + clusteredColumns + location;
        sql += ";\n";

        return sql;
    }

    string processTableName(const string &tableName)
    {
        string result = trim(tableName);

        if (!result.empty() && result[0] == '`' && result[result.length() - 1] == '`')
        {
            result = result.substr(1, result.length() - 2);
        }

        if (result.find(' ') != string::npos || result.find('.') != string::npos)
        {
            if (result[0] != '"')
            {
                result = "\"" + result + "\"";
            }
        }

        return result;
    }

    string sanitizeStageName(const string &tableName)
    {
        if (tableName.empty())
            return "default_stage";

        string stageName = tableName;
        stageName.erase(remove(stageName.begin(), stageName.end(), '"'), stageName.end());
        replace(stageName.begin(), stageName.end(), '.', '_');
        replace(stageName.begin(), stageName.end(), ' ', '_');

        string sanitized;
        sanitized.reserve(stageName.length());

        for (char c : stageName)
        {
            if (isalnum(c) || c == '_')
            {
                sanitized += c;
            }
            else
            {
                sanitized += '_';
            }
        }

        if (!sanitized.empty() && isdigit(sanitized[0]))
        {
            sanitized = "s_" + sanitized;
        }

        return sanitized + "_stage";
    }
};

// Main conversion function
void convertHiveToSnowflake(const string &hiveSql)
{
    StringProcessor processor;
    string processedSql = processor.processString(hiveSql);
    try
    {
        // 使用静态转换器避免重复构造
        static HiveToSnowflakeConverter converter;
        converter.external_table_auto_refresh = true;
        converter.external_table_bucket_prefix = "s3://s3_mybucket";
        converter.external_table_aws_sns_topic = "arn:aws:sns:us-west-2:001234567890:s3_mybucket";
        converter.external_table_aws_key_id = "AKIAXX";
        converter.external_table_aws_secret_key = "xxx";
        converter.external_table_field_delimiter = ",";
        converter.external_table_field_skip_header = 1;

        string snowflakeSql = converter.createTable(processedSql);

        if (snowflakeSql.empty())
        {
            cout << "Error: Conversion returned empty or null result" << endl;
        }
        else
        {
            cout << snowflakeSql << endl;
        }
    }
    catch (const exception &ex)
    {
        cout << "Error:" << ex.what() << endl;
    }
}

int main()
{
    vector<pair<string, string>> testCases = {
        {"Basic table with partitioning", R"(
CREATE TABLE IF NOT EXISTS `hhf hjj`.example_table(
id INT COMMENT 'Unique ID',
name STRING COMMENT 'User Name',
scores ARRAY<INT> COMMENT 'List of scores',
amount Decimal(10, 2),
metadata MAP<STRING,STRING> COMMENT 'Key-value metadata',
event_time TIMESTAMP COMMENT 'Event timestamp'
)
COMMENT 'Example table for conversion'
PARTITIONED BY(region STRING)
STORED AS ORC;)"},

        {"External table", R"(
CREATE EXTERNAL TABLE sales_data(
transaction id BIGINT,
customer id INT,
product_name STRING,
sale_amount DECIMAL(10, 2),
sale_date DATE
)
PARTITIONED BY(year INT, month INT)
STORED AS PARQUET
LOCATION '/path/to/sales/data';)"},

        {"Temporary table",
         R"(
CREATE TEMPORARY TABLE temp_analysis(
user_id INT,
session_count BIGINT,
avg_duration DOUBLE
)
STORED AS TEXTEILE;)"},

        {"Table with clustering", R"(
CREATE TABLE user_events(
event_id BIGINT,
user_id INT, 
event_type STRING,
timestamp TIMESTAMP
)
CLUSTERED BY (user_id) INTO 32 BUCKETS
STORED AS ORC;)"},

        {"Simple table without partitioning", R"(
CREATE TABLE simple_table(
id INT, 
name STRING,
created_at TIMESTAMP
)
STORED AS TEXTFILE;)"},

        {"Table with OR REPLACE", R"(
CREATE OR REPLACE TABLE products(
product_id INT,
product_name STRING,
price DECIMAL(8,2),
category STRING
)
COMMENT 'Product catalog table'
STORED AS PARQUET;)"},

        {"External table with OR REPLACE", R"(
CREATE OR REPLACE EXTERNAL TABLE external_orders(
order_id INT,
customer_id INT,
order_date DATE,
total_amount DECIMAL(10,2)
)
PARTITIONED BY(year INT, month INT)
STORED AS AVRO
LOCATION '/path/to/external/orders';)"},

        {"Temporary table with OR REPLACE", R"(
CREATE OR REPLACE TEMPORARY TABLE temp_stats(
metric_name STRING,
metric_value DOUBLE,
calculated_at TIMESTAMP
)
STORED AS TEXTFILE;)"},

        {"Advanced combined syntax test", R"(
CREATE OR REPLACE EXTERNAL TABLE complexexternal(
id BIGINT,
data STRING,
processed_at TIMESTAMP
)
PARTITIONED BY(date_partition DATE)
STORED AS PARQUET
LOCATION/complex/path/data';)"},

        {"Table with special characters in comment", R"(
CREATE TABLE test_comments(
id INT,
name STRING,
value DECIMAL(10,2)
)
COMMENT 'This is a test table with ''quoted'' text and special chars: @#$'
STORED AS PARQUET;)"},

        {"Table with complex data types", R"(
CREATE TABLE complex_types(
id INT,
user_scores ARRAY<INT>,
user_metadata MAP<STRING,STRING>,
user_profile STRUCT<name:STRING, age:INT, active:BOOLEAN>,
price DECIMAL(15,2),
description VARCHAR(500)
)
COMMENT 'Test table with complex Hive data types'
STORED AS PARQUET;)"}};

    for (size_t i = 0; i < testCases.size(); i++)
    {
        const auto &testCase = testCases[i];
        cout << "\n=== Test Case " << (i + 1) << ":" << testCase.first << " === " << endl;
        try
        {
            convertHiveToSnowflake(testCase.second);
            cout << "Test Case " << (i + 1) << " completed successfully." << endl;
        }
        catch (const exception &ex)
        {
            cout << "Test Case " << (i + 1) << " failed with error: " << ex.what() << endl;
        }
    }
    return 0;
}